home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / 7up_pd / block3.c < prev    next >
C/C++ Source or Header  |  1998-10-29  |  27KB  |  1,006 lines

  1. /* Textblöcke bearbeiten */
  2. /*****************************************************************************
  3. *
  4. *                                             7UP
  5. *                                      Modul: BLOCK.C
  6. *                                    (c) by TheoSoft '90
  7. *
  8. *****************************************************************************/
  9. #include <portab.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include <aes.h>
  15. #include <vdi.h>
  16.  
  17. #include "alert.h"
  18.  
  19. #include "7up.h"
  20. #include "windows.h"
  21.  
  22. #include "undo.h"
  23.  
  24. #define VERTICAL    1
  25. #define HORIZONTAL 2
  26.  
  27. void Wtxtdraw();
  28. void mark_line(WINDOW *wp, LINESTRUCT *str, int line);
  29. LINESTRUCT *beg_blk(WINDOW *wp, LINESTRUCT *cutbeg, LINESTRUCT *cutend);
  30. LINESTRUCT *end_blk(WINDOW *wp, LINESTRUCT **cutbeg, LINESTRUCT **cutend);
  31. int cut_blk(WINDOW *wp, LINESTRUCT *cutbeg, LINESTRUCT *cutend);
  32. int copy_blk(WINDOW *wp, LINESTRUCT *cutbeg, LINESTRUCT *cutend, LINESTRUCT **copybeg, LINESTRUCT **copyend);
  33. void paste_blk(WINDOW *wp,LINESTRUCT *beg,LINESTRUCT *end);
  34. int cut_col(WINDOW *wp, LINESTRUCT *cutbeg, LINESTRUCT *cutend);
  35. int copy_col(WINDOW *wp, LINESTRUCT *cutbeg, LINESTRUCT *cutend, LINESTRUCT **copybeg, LINESTRUCT **copyend);
  36. void paste_col(WINDOW *wp,LINESTRUCT *beg,LINESTRUCT *end);
  37. int ins_char(WINDOW *wp,LINESTRUCT *line, int c); /* neues zeichen einfügen */
  38. int ins_line(WINDOW *wp);                                 /* neue zeile einfügen */
  39. int backspace(WINDOW *wp,LINESTRUCT *line);         /* zeichen löschen */
  40. int del_char(WINDOW *wp,LINESTRUCT *line);            /* zeichen löschen */
  41. int del_line(WINDOW *wp);                                 /* zeile löschen */
  42. int cat_line(WINDOW *wp);                                 /* zeilen verbinden */
  43. void hide_blk(WINDOW *wp,LINESTRUCT *beg,LINESTRUCT *end);
  44. void free_blk(WINDOW *wp,LINESTRUCT *line);
  45. void shlf_line(WINDOW *wp, LINESTRUCT *begcut,  LINESTRUCT *endcut);
  46. void shrt_line(WINDOW *wp, LINESTRUCT *begcut,  LINESTRUCT *endcut);
  47. int adjust_best_position(WINDOW *wp);
  48. refresh(WINDOW *wp, LINESTRUCT *line, int col, int row);
  49. void swap(int *, int *);
  50.  
  51. extern int vdihandle,xdesk,ydesk,wdesk,hdesk;
  52. extern int /*clipbrd,*/cut;
  53.  
  54. extern LINESTRUCT *lastwstr;
  55. extern long        lasthfirst;
  56. extern long        begline,     endline;
  57. static WINDOW *copywindow;
  58.  
  59. LINESTRUCT *beg_blk(WINDOW *wp, LINESTRUCT *begcut, LINESTRUCT *endcut)
  60. {
  61.     if(!wp)
  62.         return(NULL);
  63.     if(cut)                  /* gibt es erst noch müll zu löschen */
  64.         free_blk(wp,begcut);
  65.     else
  66.         hide_blk(wp,begcut,endcut);
  67.     lastwstr=wp->wstr;
  68.     lasthfirst=wp->hfirst;
  69.     begcut=wp->cstr;                                        /* blk beginn */
  70.     begcut->begcol=wp->col+wp->wfirst/wp->wscroll; /* erste spalte */
  71.     begcut->endcol=STRING_LENGTH;
  72.     begline=wp->row+wp->hfirst/wp->hscroll;          /* erste zeile */
  73.     copywindow=wp;
  74.     return(begcut);
  75. }
  76.  
  77. LINESTRUCT *end_blk(WINDOW *wp, LINESTRUCT **begcut, LINESTRUCT **endcut)    /* blockende */
  78. {
  79.     register LINESTRUCT *help;
  80.     register long i,y,line;
  81.  
  82.     *endcut=NULL;         /* erstmal */
  83.     if(!wp)
  84.         return(NULL);
  85.     if(wp!=copywindow)
  86.         return(NULL);
  87.     copywindow=NULL;
  88.  
  89.     if(*begcut && !(wp->w_state&COLUMN))                                      /* mindestens eine zeile */
  90.     {
  91.         endline=wp->row+wp->hfirst/wp->hscroll;          /* für zeilendifferenz */
  92.         *endcut=wp->cstr;                                      /* ende markieren */
  93.         (*endcut)->endcol=wp->col+wp->wfirst/wp->wscroll; /* letzte spalte */
  94.         if(*begcut!=*endcut)                 /* Anfang nicht überschreiben */
  95.             (*endcut)->begcol=0;
  96.         if(*begcut==*endcut)
  97.             if((*begcut)->begcol>(*endcut)->endcol)
  98.                 swap(&(*begcut)->begcol,&(*endcut)->endcol);
  99.         if(begline>endline)
  100.         {
  101. /* Das fehlte hier!!! Erik Dick */
  102.             lastwstr=wp->wstr;
  103.             lasthfirst=wp->hfirst;
  104.  
  105.             help=*endcut;
  106.             *endcut=*begcut;
  107.             *begcut=help;
  108.  
  109.             line=begline;
  110.             begline=endline;
  111.             endline=line;
  112.  
  113.             (*begcut)->begcol=(*begcut)->endcol;
  114.             (*begcut)->endcol=STRING_LENGTH;
  115.  
  116.             (*endcut)->endcol=(*endcut)->begcol;
  117.             (*endcut)->begcol=0;
  118.         }
  119.         if((*endcut)->endcol==0)  /* wenn spalte=0, (*endcut) zurücksetzen... */
  120.         {
  121.             if((*endcut) != (*begcut))  /* ...wenn (*endcut) > (*begcut)                    */
  122.             {
  123.                 (*endcut)=(*endcut)->prev;
  124.                 if((*begcut) != (*endcut))
  125.                     (*endcut)->begcol=0;
  126.                 (*endcut)->endcol=STRING_LENGTH;
  127.                 endline--;
  128.             }
  129.             else
  130.                 return(NULL);
  131.         }
  132.         if((*begcut)->begcol==0 && (*endcut)->endcol>=(*endcut)->used)
  133.         {
  134.             endline++;
  135.         }
  136.         for(help=(*begcut); help != (*endcut)->next; help=help->next)
  137.         {
  138.             help->attr|=SELECTED;                                         /* attribut setzen */
  139.         }
  140.         if((*begcut) != (*endcut)) /* mehr als eine zeile */
  141.             for(help=(*begcut)->next; help && help != (*endcut); help=help->next)
  142.             {
  143.                 help->begcol=0;
  144.                 help->endcol=STRING_LENGTH;
  145.             }
  146.         for(help=wp->wstr,i=0,y=wp->ywork;
  147.              help && y<(wp->ywork+wp->hwork-1);
  148.              help=help->next, i++, y+=wp->hscroll)
  149.             if(help->attr & SELECTED)
  150.             {
  151.                 mark_line(wp,help,i);
  152.             }
  153.     }
  154.     if((*begcut) && (wp->w_state&COLUMN)) /* Spaltenblock setzen */
  155.     {
  156.         endline=wp->row+wp->hfirst/wp->hscroll;          /* für zeilendifferenz */
  157.         (*endcut)=wp->cstr;                                        /* ende markieren */
  158.         (*endcut)->begcol=(*begcut)->begcol;
  159.         (*begcut)->endcol=(*endcut)->endcol=wp->col+wp->wfirst/wp->wscroll; /* letzte spalte */
  160.         if(begline>endline)
  161.         {
  162.             help=(*endcut);
  163.             (*endcut)=(*begcut);
  164.             (*begcut)=help;
  165.  
  166.             line=begline;
  167.             begline=endline;
  168.             endline=line;
  169.         }
  170.         if((*begcut)->begcol>(*endcut)->endcol)
  171.             swap(&(*begcut)->begcol,&(*endcut)->endcol);
  172.         for(help=(*begcut); help != (*endcut)->next; help=help->next)
  173.         {
  174.             help->attr|=SELECTED;                                         /* attribut setzen */
  175.         }
  176. /*
  177.         if((*begcut) != (*endcut)) /* mehr als eine zeile */
  178. */
  179.             for(help=(*begcut); help && help != (*endcut)->next; help=help->next)
  180.             {
  181.                 help->begcol=(*begcut)->begcol;
  182.                 help->endcol=(*endcut)->endcol;
  183.             }
  184.         for(help=wp->wstr,i=0,y=wp->ywork;
  185.              help && y<(wp->ywork+wp->hwork-1);
  186.              help=help->next, i++, y+=wp->hscroll)
  187.             if(help->attr & SELECTED)
  188.             {
  189.                 mark_line(wp,help,i);
  190.             }
  191.     }
  192.     return(*endcut);
  193. }
  194.  
  195. void mark_all(WINDOW *wp, LINESTRUCT **begcut, LINESTRUCT **endcut)
  196. {
  197.     register long i,y,maxlen=0;
  198.     LINESTRUCT *help;
  199.     long lines,chars;
  200.     if(wp)
  201.     {
  202.         Wtxtsize(wp,&lines,&chars);
  203.         if(lines && chars)
  204.         {
  205.             if(cut)                  /* gibt es erst noch müll zu löschen */
  206.                 free_blk(wp,*begcut);
  207.             else
  208.                 hide_blk(wp,*begcut,*endcut);
  209.             if((wp->w_state&COLUMN))
  210.             {
  211.                 for(help=wp->fstr; help; help=help->next)
  212.                     maxlen=max(help->used,maxlen);
  213.             }
  214.             lastwstr=wp->wstr;
  215.             lasthfirst=wp->hfirst;
  216. /* MT 12.5.95
  217.             begline=1L;
  218.             endline=1L;
  219. */
  220.             begline=endline=0L;
  221.             for(*begcut=help=wp->fstr; help; help=help->next)
  222.             {
  223.                 endline++;
  224.                 help->attr|=SELECTED;
  225.                 help->begcol=0;
  226.                 help->endcol=((wp->w_state&COLUMN)?maxlen:STRING_LENGTH);
  227.                 *endcut=help;
  228.             }
  229.             for(help=wp->wstr,i=0,y=wp->ywork;
  230.                  help && y<(wp->ywork+wp->hwork-1);
  231.                  help=help->next, i++, y+=wp->hscroll)
  232.             {
  233.                 if(help->attr & SELECTED)
  234.                     mark_line(wp,help,i);
  235.             }
  236.             return;
  237.         }
  238.     }
  239.     *begcut=*endcut=NULL;
  240. }
  241.  
  242. /* auszuschneidedenden Blockanfang und -ende verschieben bzw. kürzen */
  243. static beg_end(LINESTRUCT *begcut, LINESTRUCT *endcut)/* korrekt */
  244. {
  245.     strcpy(begcut->string,&begcut->string[begcut->begcol]);
  246.     endcut->string[min(endcut->used,endcut->endcol)-endcut->begcol]=0;
  247.     begcut->used=strlen(begcut->string);
  248.     endcut->used=strlen(endcut->string);
  249.     begcut->begcol=0;            /* anfang erst zum schluß ändern */
  250.     endcut->begcol=0;
  251. }
  252.  
  253. static LINESTRUCT *newline(LINESTRUCT *begcut, LINESTRUCT *endcut)
  254. {
  255.     LINESTRUCT *new;
  256.  
  257.     if((new=malloc(sizeof(LINESTRUCT)))==NULL)
  258.         return(NULL);                            /* was ist wenn endcut NULL ist??? */
  259.     if((new->string=malloc(begcut->begcol+(endcut->used-min(endcut->endcol,endcut->used))+1))==NULL)
  260.     {
  261.         free(new);
  262.         return(NULL);
  263.     }
  264.     strncpy(new->string,begcut->string,begcut->begcol);
  265.     strcpy(&new->string[begcut->begcol],&endcut->string[min(endcut->endcol,endcut->used)]);
  266.     new->len=new->used=strlen(new->string);
  267.     if(!new->used)
  268.     {
  269.         free(new->string);
  270.         free(new);
  271.         return(NULL);
  272.     }
  273.     new->prev=new->next=NULL;
  274.     new->begcol=0;
  275.     new->endcol=STRING_LENGTH;
  276.     new->attr=0;
  277.     new->effect=0;
  278.     beg_end(begcut,endcut);        /* erste und letzte Zeile, */
  279.                                              /* verschieben bzw. kürzen */
  280.     return(new);
  281. }
  282.  
  283. static LINESTRUCT *newwstr(WINDOW *wp, long begline)
  284. {
  285.     LINESTRUCT *line;
  286.     register long i;
  287.     for(i=0,line=wp->fstr; i<begline; i++)
  288.         line=line->next;
  289.     return(line);
  290. }
  291.  
  292. int cut_blk(WINDOW *wp, LINESTRUCT *beg,  LINESTRUCT *end)  /* ausschneiden */
  293. {
  294.     register LINESTRUCT *new,*help;
  295.     register long i,y,lline=FALSE;
  296.     int full[4],area[4];
  297.     long hfirst;
  298.     GRECT rect;
  299.  
  300.     if(!wp)
  301.         return(FALSE);
  302.  
  303.     if(beg && end && endline>=begline ) /* anfang und ende müssen bekannt sein */
  304.     {
  305.         for(help=wp->wstr,i=0,y=wp->ywork;
  306.              help && y<(wp->ywork+wp->hwork-1);
  307.              help=help->next, i++, y+=wp->hscroll)
  308.             if(help->attr & SELECTED)
  309.                 mark_line(wp,help,i);
  310.         for(help=beg; help != end->next; help=help->next)
  311.             help->attr&=~SELECTED;
  312.  
  313.         if(!beg->prev && !end->next) /* gesammten Text cuten */
  314.         {
  315. /**/
  316.             wp->cspos=wp->col=wp->row=0;
  317. /**/
  318.             wp->hfirst=wp->hsize=0;
  319.             if((wp->cstr=newline(beg,end))==NULL) /* neue Zeile, umkopieren  */
  320.                 ins_line(wp);
  321.             else
  322.                 wp->hsize=wp->hscroll;
  323.             wp->cstr->prev=wp->cstr->next=NULL;
  324.             wp->fstr=wp->wstr=wp->cstr;
  325.             Wredraw(wp,&wp->xwork);
  326.             wp->w_state |= CHANGED;
  327.             return(TRUE);
  328.         }
  329. /* entfernt, wurde massiv kritisiert
  330.         if(isspace(end->string[end->endcol])) /* intelligent CUT */
  331.         {
  332.             for(i=end->endcol; i<wp->cstr->used; i++)
  333.                 if(isspace(end->string[i]))
  334.                     break;
  335.             for(i; i<wp->cstr->used; i++)
  336.                 if(!isspace(end->string[i]))
  337.                     break;
  338.             end->endcol=i;
  339.         }
  340. */
  341.         wp->cspos=wp->col=beg->begcol;/* beg->begcol geht in newline()/beg_end() verloren */
  342.         wp->row=begline-wp->hfirst/wp->hscroll;
  343.         if((new=newline(beg,end))!=NULL) /* neue Zeile, umkopieren  */
  344.         {
  345.             if(beg->prev)                         /* Zeile davor vorhanden */
  346.             {
  347.                 beg->prev->next=new;          /* Anfang verknüpfen */
  348.                 new->prev=beg->prev;
  349.                 wp->cstr=new;                         /* cursor auf neuen Anfang */
  350.             }
  351.             else
  352.             {
  353.                 wp->fstr=wp->wstr=wp->cstr=new;  /* erste Textzeile ist neu */
  354.             }
  355.             if(end->next)                         /* nachfolger vorhanden */
  356.             {
  357.                 new->next=end->next;          /* Ende verknüpfen */
  358.                 end->next->prev=new;
  359.             }
  360.         }
  361.         else                                             /* keine neue Zeile */
  362.         {
  363.             if(beg->prev && end->next)  /* Text aus der Mitte */
  364.             {
  365.                 beg->prev->next=end->next; /* Anfang... */
  366.                 end->next->prev=beg->prev; /* ... und Ende verknüpfen */
  367.                 wp->cstr=end->next;             /* Cursor setzen */
  368.             }
  369.             if(!beg->prev && end->next)    /* kein Vorgänger, aber Nachfolger */
  370.             {
  371.                 wp->fstr=wp->wstr=wp->cstr=end->next; /* Textanfang ausschneiden */
  372.                 wp->fstr->prev=NULL;
  373.             }
  374.             if(beg->prev && !end->next)    /* Vorgänger, aber kein Nachfolger */
  375.             {
  376.                 wp->cstr=beg->prev;             /* Cursor setzen */
  377.                 wp->cstr->next=NULL;              /* Ende markieren */
  378.                 wp->row--;
  379.                 lline=TRUE;
  380.              }
  381.         }
  382. /*  Neuberechnung der ersten Fensterzeile in Abhängigkeit der letzten Pos */
  383.         wp->wstr=newwstr(wp,lasthfirst/wp->hscroll);
  384.  
  385.         wp->hsize-=(endline-begline) * wp->hscroll; /* Länge um Zeilendifferenz kürzen */
  386.         hfirst=wp->hfirst;
  387.         wp->hfirst=lasthfirst;                            /* ...wiederherstellen  */
  388.  
  389.         if(!adjust_best_position(wp))                 /* Anfang muß nicht verschoben werden */
  390.         {
  391.             if(wp->hfirst==hfirst)                        /* alte wp->wstr-position bleibt */
  392.             {
  393.                 refresh(wp,wp->cstr,0,wp->row);
  394.                 if(begline!=endline)                     /* mehr als eine Zeile */
  395.                 {
  396.                     rect.g_x=wp->xwork;
  397.                     rect.g_y=wp->ywork + (wp->row+1) * wp->hscroll;
  398.                     rect.g_w=wp->wwork;
  399.                     rect.g_h=wp->hwork - (wp->row+1) * wp->hscroll;
  400.                     if(labs((endline-begline)*wp->hscroll) >= rect.g_h)
  401.                     {
  402.                         Wredraw(wp, &rect/*&wp->xwork*/);/* Bereich ganz neu zeichnen */
  403.                     }
  404.                     else
  405.                     {
  406.                         Wscroll(wp,VERTICAL,(endline-begline)*wp->hscroll,&rect);
  407.                     }
  408.                 }
  409.             }
  410.             else
  411.             {
  412.                 Wredraw(wp,&wp->xwork);
  413.             }
  414.         }
  415.         else
  416.         {
  417.             wp->row=begline-wp->hfirst/wp->hscroll; /* nochmal berechnen */
  418.             if(endline-begline == 1)
  419.             {
  420.                 rect.g_x=wp->xwork;
  421.                 rect.g_y=wp->ywork;
  422.                 rect.g_w=wp->wwork;
  423.                 rect.g_h=(wp->row) * wp->hscroll;
  424.                 Wscroll(wp,VERTICAL,-wp->hscroll,&rect);
  425.                 if(new)                         /* zusammengesetzte zeile */
  426.                     refresh(wp,new,0,wp->row);
  427.  
  428. /* Muβ drin bleiben, weil sonst vieles andere nicht mehr funktioniert */
  429.                 if((wp->cstr->prev && wp->cstr->next) || !lline)
  430.                 {                                 /* cursor zurück positionieren */
  431.                     wp->cstr=wp->cstr->prev;
  432.                     wp->row--;
  433.                 }
  434.  
  435.             }
  436.             else
  437.             {
  438.                 Wredraw(wp,&wp->xwork);
  439.             }
  440.         }
  441.         wp->w_state |= CHANGED;          /* es wurde editiert */
  442.         beg->prev=NULL;                     /* anfang und ende markieren */
  443.         end->next=NULL;
  444.         return(TRUE);
  445.     }
  446.     return(FALSE);
  447. }
  448.  
  449. int copy_blk(WINDOW *wp, LINESTRUCT *beg,  LINESTRUCT *end,  LINESTRUCT **begcopy,  LINESTRUCT **endcopy)
  450. {
  451.     register LINESTRUCT *src,*dst,*help;
  452.     register long i,y,len;
  453.  
  454.     if(!wp)
  455.         return(FALSE);
  456.  
  457.     if(beg && end && endline>=begline)
  458.     {
  459.         for(help=wp->wstr,i=0,y=wp->ywork; help /*!= end->next*/ && y<(wp->ywork+wp->hwork-1); help=help->next, i++, y+=wp->hscroll)
  460.             if(help->attr & SELECTED)
  461.                 mark_line(wp,help,i);
  462.         for(help=beg; help != end->next; help=help->next)
  463.             help->attr&=~SELECTED;
  464.  
  465.         *begcopy=NULL;
  466.         if((dst=malloc(sizeof(LINESTRUCT))) != NULL) /* copy anfang */
  467.         {
  468.             *begcopy=dst;
  469.             dst->prev=dst->next=NULL;
  470.             for(src=beg; src != end->next; src=src->next) /* anzahl kopieren */
  471.             {
  472.                 if(src->endcol<src->used)
  473.                     len=src->endcol-src->begcol;
  474.                 else
  475.                     len=src->used;
  476.                 if((dst->string=malloc(len + 1)) != NULL) /* allozieren  */
  477.                 {
  478.                     if(src->endcol<src->used)
  479.                     {
  480.                         strncpy(dst->string,&src->string[src->begcol],len);
  481.                         dst->string[len]=0;
  482.                     }
  483.                     else
  484.                         strcpy(dst->string,&src->string[src->begcol]);
  485.                     dst->len    = len;
  486.                     dst->used   = strlen(dst->string);
  487.                     dst->begcol = 0;
  488.                     dst->endcol = src->endcol;                         /*STRING_LENGTH;*/
  489.                     dst->attr   = (src->attr &= ~SELECTED);
  490.                     dst->effect = TXT_NORMAL;                        /* attribute  */
  491.                     if(src != end)
  492.                     {
  493.                         help=dst;                                                 /* merken */
  494.                         if((dst->next=malloc(sizeof(LINESTRUCT))) != NULL) /* nächste zeile allozieren */
  495.                         {
  496.                             dst=dst->next;                          /* zeiger weiter */
  497.                             dst->prev=help;          /* zeiger rückwärts verketten */
  498.                             dst->next=NULL;
  499.                             dst->attr   = 0;
  500.                             dst->effect = TXT_NORMAL;                        /* attribute  */
  501.                         }
  502.                         else
  503.                             return(-1); /* kein RAM */
  504.                     }
  505.                     else
  506.                         break;
  507.                 }
  508.                 else
  509.                     return(-1);      /* kein RAM */
  510.             }
  511.             dst->next=NULL; /* hier ist schluß */
  512.             *endcopy=dst;
  513. /* NEU: wenn CRLF erzeugt werden soll, also end->endcol=STRING_LENGTH */
  514. /* Zeilenumbruch */
  515.             if(src->endcol==STRING_LENGTH)
  516.             {
  517.                 help=dst;                                                    /* merken */
  518.                 if((dst->next=malloc(sizeof(LINESTRUCT))) != NULL) /* nächste zeile allozieren */
  519.                 {
  520.                     dst=dst->next;                             /* zeiger weiter */
  521.                     dst->prev=help;             /* zeiger rückwärts verketten */
  522.                     dst->next=NULL;
  523.                     dst->attr=0;
  524.                     dst->effect=TXT_NORMAL;
  525.                     if((dst->string=malloc(NBLOCKS + 1)) != NULL)    /* allozieren  */
  526.                     {
  527.                         dst->string[0]=0;
  528.                         dst->len  = NBLOCKS;
  529.                         dst->used = 0;
  530.                         dst->begcol=0;
  531.                         dst->endcol=0;
  532.                         *endcopy=dst;
  533.                     }
  534.                     else /* zurück, weil kein RAM */
  535.                     {
  536.                         dst=dst->prev;
  537.                         free(dst->next);
  538.                         dst->next=NULL;
  539.                     }
  540.                 }
  541. /*******/
  542.             }
  543.             return(TRUE);
  544.         }
  545.         return(-1);                  /* kein RAM */
  546.     }
  547.     return(FALSE);
  548. }
  549.  
  550. void paste_blk(WINDOW *wp,LINESTRUCT *beg, LINESTRUCT *end)
  551. {
  552.     register LINESTRUCT *help;
  553.     register int abscol;
  554.     GRECT rect;
  555.     long lines, chars, oldsize;
  556.     char *help1,*help2;
  557.     int full[4],area[4];
  558.  
  559.     if(!wp)
  560.         return;
  561.     if(beg && end)
  562.     {
  563.         abscol=wp->col+wp->wfirst/wp->wscroll; /* absolute Spalte */
  564.  
  565.         if(abscol>wp->cstr->used) /* beim neuformatieren */
  566.             abscol=wp->cstr->used;
  567.  
  568.         if((help2=realloc(end->string,end->used+strlen(&wp->cstr->string[abscol])+1))==NULL)
  569.             return;                                      /* hinten zusammenkopieren */
  570.         end->string=help2;
  571.  
  572.         strcat(end->string,&wp->cstr->string[abscol]);
  573.         end->len=end->used=strlen(end->string);
  574.  
  575.         end->next=wp->cstr->next;
  576.         if(wp->cstr->next)
  577.             wp->cstr->next->prev=end;
  578.  
  579.         if((help1=realloc(wp->cstr->string,wp->cstr->used+beg->used+1))==NULL)
  580.             return;                                         /* vorn zusammenkopieren */
  581.         wp->cstr->string=help1;
  582.  
  583.         strcpy(&wp->cstr->string[abscol],beg->string);
  584.         wp->cstr->len=wp->cstr->used+beg->used;
  585.         wp->cstr->used=strlen(wp->cstr->string);
  586.  
  587.         wp->cstr->next=beg->next;
  588.         if(beg->next)
  589.             beg->next->prev=wp->cstr;
  590.  
  591.         oldsize=wp->hsize;
  592.         Wtxtsize(wp,&lines,&chars);
  593.         wp->hsize=lines*wp->hscroll;
  594.  
  595.         refresh(wp,wp->cstr,wp->col,wp->row);
  596.         rect.g_x=wp->xwork;
  597.         rect.g_y=wp->ywork + (int)((wp->row+1) * wp->hscroll);
  598.         rect.g_w=wp->wwork;
  599.         rect.g_h=wp->hwork - (int)((wp->row+1) * wp->hscroll);
  600.         if(wp->hsize-oldsize) /* !=0 */
  601.         {
  602.             if(labs(wp->hsize-oldsize) >= rect.g_h)
  603.             {
  604.                 Wredraw(wp, &rect/*&wp->xwork*/); /* Bereich ganz neu zeichnen */
  605.             }
  606.             else
  607.             {
  608.                 Wscroll(wp,VERTICAL,-(wp->hsize-oldsize),&rect);
  609.             }
  610.         }
  611.         wp->w_state |= CHANGED;
  612.     }
  613. }
  614.  
  615. /**************************************************************************
  616. *
  617. *  Spaltenblockfunktionen
  618. *
  619. ***************************************************************************/
  620.  
  621.  
  622. int cut_col(WINDOW *wp, LINESTRUCT *beg,  LINESTRUCT *end)  /* ausschneiden */
  623. {
  624.     register long i,y,row,diff;
  625.     static LINESTRUCT *begcopy,*endcopy;
  626.     register LINESTRUCT *help;
  627.     extern LINESTRUCT *begcut,*endcut;
  628.  
  629.     if(!wp)
  630.         return(FALSE);
  631.  
  632.     if(beg && end && endline>=begline ) /* anfang und ende müssen bekannt sein */
  633.     {
  634.         if((cut=copy_col(wp,beg,end,&begcopy,&endcopy))>0)
  635.         {
  636.          wp->cspos=wp->col=beg->endcol-wp->wfirst/wp->wscroll; /* ans Ende setzen, wg. Block übertippen */
  637.             diff=beg->endcol-beg->begcol;
  638.             for(help=beg; help && help!=end->next; help=help->next)
  639.             {
  640.                 if(help->endcol<help->used)
  641.                 {
  642.                     memmove(&help->string[help->begcol],&help->string[help->endcol],strlen(&help->string[help->endcol])+1);
  643.                 }
  644.                 else
  645.                 {
  646.                     if(help->begcol<help->used)/* evtl. Leerzeile berücksichtigen */
  647.                         help->string[help->begcol]=0;
  648.                 }
  649.                 help->used=strlen(help->string);
  650.                 help->attr&=~SELECTED;
  651.             }
  652.             for(help=wp->wstr,i=0,y=wp->ywork;
  653.                  help && y<(wp->ywork+wp->hwork-1);
  654.                  help=help->next, i++, y+=wp->hscroll)
  655.                 refresh(wp,help,beg->begcol-wp->wfirst/wp->wscroll,i);
  656.  
  657.             wp->col-=diff;
  658. /**/
  659.             wp->cspos-=diff;
  660. /**/
  661.             begcut=begcopy;
  662.             endcut=endcopy;
  663.             wp->w_state|=CHANGED;
  664.             return(TRUE);
  665.         }
  666.     }
  667.     return(FALSE);
  668. }
  669.  
  670. void blank(char *s, int n)  /* evtl. mit blanks auffüllen */
  671. {
  672.     register int k;
  673.     k=strlen(s);
  674.     if(k < n)
  675.     {
  676.         memset(&s[k],' ',n-k);
  677.         s[n]=0;
  678.     }
  679. }
  680.  
  681. int copy_col(WINDOW *wp, LINESTRUCT *begcut,  LINESTRUCT *endcut,  LINESTRUCT **begcopy,  LINESTRUCT **endcopy)
  682. {
  683.     register LINESTRUCT *src,*dst,*help;
  684.     register long i,y;
  685.     if(!wp)
  686.         return(FALSE);
  687.  
  688.     if(begcut && endcut && endline>=begline ) /* anfang und ende müssen bekannt sein */
  689.     {
  690.         for(help=wp->wstr,i=0,y=wp->ywork; help /*!= end->next*/ && y<(wp->ywork+wp->hwork-1); help=help->next, i++, y+=wp->hscroll)
  691.             if(help->attr & SELECTED)
  692.                 mark_line(wp,help,i);
  693.         for(help=begcut; help != endcut->next; help=help->next)
  694.             help->attr&=~SELECTED;
  695.  
  696.         *begcopy=NULL;
  697.         if((dst=malloc(sizeof(LINESTRUCT))) != NULL) /* copy anfang */
  698.         {
  699.             *begcopy=dst;
  700.             dst->prev=dst->next=NULL;
  701.             for(src=begcut; src != endcut->next; src=src->next) /* anzahl kopieren */
  702.             {
  703.                 if((dst->string=malloc(src->endcol-src->begcol + 1)) != NULL)  /* allozieren  */
  704.                 {
  705.                     if(src->begcol < src->used)                /* block < stringlänge */
  706.                     {
  707.                         strncpy(dst->string,&src->string[src->begcol],
  708.                             src->endcol-src->begcol);        /* block herauskopieren */
  709.                         dst->string[src->endcol-src->begcol]=0;      /* ende setzen */
  710.                         blank(dst->string,src->endcol-src->begcol);/* evtl. blanks */
  711.                     }
  712.                     else            /* block jenseits stringende, mit blanks füllen */
  713.                     {
  714.                         memset(dst->string,' ',src->endcol-src->begcol);
  715.                         dst->string[src->endcol-src->begcol]=0;
  716.                     }
  717.                     dst->used = dst->len = strlen(dst->string);    /* länge         */
  718. /*
  719.                     fprintf(stderr,"%s\n",dst->string);
  720. */
  721.                     dst->begcol=0;              /*src->begcol;*/
  722.                     dst->endcol=dst->used;     /*src->endcol;*/
  723.                     dst->attr  =(src->attr &= ~SELECTED);                            /* attribute  */
  724.                     dst->effect=TXT_NORMAL;
  725.                     if(src != endcut)
  726.                     {
  727.                         help=dst;                                                     /* merken */
  728.                         if((dst->next=malloc(sizeof(LINESTRUCT))) != NULL) /* nächste zeile allozieren */
  729.                         {
  730.                             dst=dst->next;                             /* zeiger weiter */
  731.                             dst->prev=help;             /* zeiger rückwärts verketten */
  732.                             dst->next=NULL;
  733.                         }
  734.                         else
  735.                             return(-1);  /* kein RAM */
  736.                     }
  737.                     else
  738.                         break;
  739.                 }
  740.                 else
  741.                     return(-1);        /* kein RAM */
  742.             }
  743.             dst->next=NULL; /* hier ist schluß */
  744.             *endcopy=dst;
  745.             return(TRUE);
  746.         }
  747.         return(-1);                    /* kein RAM */
  748.     }
  749.     return(FALSE);
  750. }
  751.  
  752. char *strins(char *dst, char *ins, int idx)
  753. {
  754.     memmove(&dst[idx+strlen(ins)],&dst[idx],strlen(&dst[idx])+1);
  755.     memmove(&dst[idx],ins,strlen(ins));
  756.     return(dst);
  757. }
  758.  
  759. static int ins_str(LINESTRUCT *dst, LINESTRUCT *src, int abscol) /* einfügen */
  760. {
  761.     char *help;
  762.     int len;
  763.     if(abscol < dst->used) /* jenachdem ob abscol > dst->used */
  764.     {
  765.         len=dst->used+src->used;
  766.     }
  767.     else
  768.     {
  769.         len=abscol+src->used;
  770.     }
  771.     if(dst->len < len)                    /* neue länge > alte */
  772.     {
  773.         if((help=realloc(dst->string,len+1))==NULL)
  774.         {
  775.             return(FALSE);
  776.         }
  777.         dst->string=help;
  778.         dst->len=len;
  779.     }
  780.     if(abscol < dst->used)                     /* innerhalb des strings einfügen */
  781.     {
  782.         strins(dst->string, src->string, abscol);
  783.     }
  784.     else                                                                 /* hinten anhängen */
  785.     {
  786.         memset(&dst->string[dst->used],' ',abscol-dst->used); /* blanks auffüllen */
  787.         dst->string[abscol]=0;
  788.         strcat(dst->string,src->string);
  789.     }
  790.     dst->len=dst->used=strlen(dst->string);
  791.     return(TRUE);
  792. }
  793.  
  794. void paste_col(WINDOW *wp,LINESTRUCT *beg, LINESTRUCT *end)
  795. {
  796.     register LINESTRUCT *dst,*src;
  797.     register long i,y,abscol,count=0;
  798.     GRECT rect;
  799.  
  800.     if(!wp)
  801.         return;
  802.  
  803.     if(beg && end)
  804.     {
  805.         abscol=wp->col+wp->wfirst/wp->wscroll;
  806.         for(dst=wp->cstr,src=beg;
  807.              dst && src!=end->next;
  808.              dst=dst->next,src=src->next)
  809.         {
  810.             if(!ins_str(dst,src,abscol))
  811.             {
  812.                 form_alert(1,Ablock[0]);
  813.                 break;
  814.             }
  815.             count++;
  816.         }
  817.         for(i=wp->row,dst=wp->cstr;
  818.              i<wp->row+count && i<wp->hwork/wp->hscroll && dst;
  819.              i++,dst=dst->next)
  820.             refresh(wp,dst,wp->col,i);
  821.         wp->w_state |= CHANGED;
  822.     }
  823. }
  824.  
  825. void hide_blk(WINDOW *wp, LINESTRUCT *beg, LINESTRUCT *end) /* blockmarkierung löschen */
  826. {
  827.     register LINESTRUCT *help;
  828.     extern LINESTRUCT *begcut,*endcut;
  829.     extern char searchstring[];
  830.     register long i,y;
  831.  
  832.     if(!wp)
  833.         return;
  834.     if(beg && end) /* naja, dürfte wohl klar sein */
  835.     {
  836.         graf_mouse(M_OFF,NULL);
  837.         Wcursor(wp);
  838.         for(help=wp->wstr,i=0,y=wp->ywork;
  839.              help && y<(wp->ywork+wp->hwork-1);
  840.              help=help->next, i++, y+=wp->hscroll)
  841.             if(help->attr & SELECTED)
  842.             {
  843.                 mark_line(wp,help,i);
  844.             }
  845.         for(help=wp->fstr; help; help=help->next)
  846.         {
  847.             help->attr&=~SELECTED;
  848.             help->begcol=0;
  849.             help->endcol=STRING_LENGTH;
  850.         }
  851.         cut=FALSE;
  852.         begline=endline=NULL;
  853.         begcut=endcut=NULL;/* in 7up.c auf NULL setzen, damit sind sie ungültig */
  854.         *searchstring=0;
  855. /**/
  856.         Wcuron(wp);
  857. /**/
  858.         Wcursor(wp);
  859.         graf_mouse(M_ON,NULL);
  860.     }
  861. }
  862.  
  863. void free_blk(WINDOW *wp,LINESTRUCT *line) /* block aus dem speicher löschen */
  864. {
  865.     extern LINESTRUCT *begcut,*endcut;
  866.     if(!wp)
  867.         return;
  868.     if(line)
  869.     {
  870.         do
  871.         {
  872.             if(line->string)
  873.                 free(line->string);
  874.             if(line->prev)
  875.                 free(line->prev);
  876.             if(line->next)
  877.                 line=line->next;
  878.             else
  879.             {
  880.                 free(line);
  881.                 line=NULL;
  882.             }
  883.         }
  884.         while(line);
  885.         cut=FALSE;
  886.         begline=endline=NULL;
  887.         begcut=endcut=NULL;/* in 7up.c auf NULL setzen, damit sind sie ungültig */
  888.     }
  889. }
  890.  
  891. void shlf_line(WINDOW *wp, LINESTRUCT *begcut,  LINESTRUCT *endcut)
  892. {
  893.     register LINESTRUCT *help;
  894.     register long i,y,indent;
  895.     int ret, kstate;
  896.     
  897.     if(!wp)
  898.         return;
  899.     if(begcut && endcut)
  900.     {
  901.         graf_mkstate(&ret, &ret, &ret, &kstate);
  902.         if(kstate & (K_RSHIFT|K_LSHIFT)) 
  903.            indent=1;
  904.         else
  905.            indent=wp->tab;
  906.         graf_mouse(M_OFF,NULL);
  907.         Wcursor(wp);
  908.         wp->col=0;
  909.         for(help=begcut; help != endcut->next; help=help->next)
  910.         {
  911.             if(help->attr & SELECTED)
  912.             {
  913.                 for(i=0; i<indent; i++)
  914.                 {
  915.                     if((wp->w_state&COLUMN))
  916.                     {
  917.                         wp->col=help->begcol-wp->wfirst/wp->wscroll;
  918.                         if(!(wp->wfirst == 0 && wp->col == 0))
  919.                         {
  920.                             if(isspace(help->string[help->begcol-1]))
  921.                             {
  922.                                 strcpy(&help->string[help->begcol-1],
  923.                                          &help->string[help->begcol]);
  924.                                 help->used--;                             /* länge kürzen */
  925.                                 help->begcol--;
  926.                                 help->endcol--;
  927.                             }
  928.                         }
  929.                     }
  930.                     else
  931.                     {
  932.                         wp->col=0;
  933.                         if(isspace(*help->string))
  934.                         {
  935.                             strcpy(help->string,&help->string[1]);
  936.                             help->used--;                             /* länge kürzen */
  937.                         }
  938.                     }
  939.                 }
  940.                 wp->col--;
  941.             }
  942.         }
  943. /*
  944.         if(--wp->col < 0)
  945.         {
  946.             Wlpage(wp,wp->col+wp->wfirst/wp->wscroll-1);
  947.             wp->col=0;
  948.         }
  949. */
  950. wp->cspos=Wshiftpage(wp,0,wp->cstr->used);
  951.         for(i=0,help=wp->wstr,y=wp->ywork; help != endcut->next && y < (wp->ywork+wp->hwork); i++,help=help->next, y+=wp->hscroll)
  952.             if(help->attr & SELECTED)
  953.             {
  954.                 refresh(wp,help,0,i);
  955.             }
  956.         wp->w_state |= CHANGED;
  957.         Wcursor(wp);
  958.         graf_mouse(M_ON,NULL);
  959.     }
  960. }
  961.  
  962. void shrt_line(WINDOW *wp, LINESTRUCT *begcut,  LINESTRUCT *endcut)
  963. {
  964.     register LINESTRUCT *help;
  965.     register long i,y,indent;
  966.     int ret, kstate;
  967.     
  968.     if(!wp)
  969.         return;
  970.     if(begcut && endcut)
  971.     {
  972.         graf_mkstate(&ret, &ret, &ret, &kstate);
  973.         if(kstate & (K_RSHIFT|K_LSHIFT)) 
  974.            indent=1;
  975.         else
  976.            indent=wp->tab;
  977.         graf_mouse(BUSY_BEE,NULL);
  978.         wp->col=0;
  979.         for(help=begcut; help != endcut->next; help=help->next)
  980.         {
  981.             wp->col=help->begcol-wp->wfirst/wp->wscroll;
  982.             if(help->attr & SELECTED)
  983.                 for(i=0; i<indent; i++)
  984.                 {
  985.                     ins_char(wp,help,' ');
  986.                     if((wp->w_state&COLUMN))
  987.                     {
  988.                         help->begcol++;
  989.                         help->endcol++;
  990.                     }
  991.                 }
  992.         }
  993.         graf_mouse(ARROW,NULL);
  994.         graf_mouse(M_OFF,NULL);
  995.         Wcursor(wp);
  996.         for(i=0,help=wp->wstr,y=wp->ywork; help != endcut->next && y < (wp->ywork+wp->hwork); i++,help=help->next, y+=wp->hscroll)
  997.             if(help->attr & SELECTED)
  998.             {
  999.                 refresh(wp,help,0 ,i);
  1000.             }
  1001.         wp->w_state |= CHANGED;
  1002.         Wcursor(wp);
  1003.         graf_mouse(M_ON,NULL);
  1004.     }
  1005. }
  1006.